package es;

import es.componentes.Componente;
import es.entidades.Entidad;
import es.gestores.GestorComponentes;
import es.gestores.GestorEntidades;
import es.gestores.GestorSubsistemas;
/**
 * Clase abstracta que representa un sistema de entidades basado en componentes.
 * @author Miguel Vicente
 */
public abstract class SistemaEntidades {
	
	private GestorEntidades gestorEntidades;
	private GestorComponentes gestorComponentes;
	private GestorSubsistemas gestorSubsistemas;
	
	/**
	 * Constructor. Crea un nuevo <code>SistemaEntidades</code>.
	 */
	public SistemaEntidades() {
		gestorEntidades = new GestorEntidades();
		gestorComponentes = new GestorComponentes();
		gestorSubsistemas = new GestorSubsistemas();
		inicializar();
	}
	/**
	 * Inicializa el contenido de los gestores. Este metodo es llamado por {@link #SistemaEntidades()}<br>
	 * - Creacion de entidades mediante el gestor de entidades.<br>
	 * - Creacion de componentes y asignacion de componentes a las entidades mediante el gestor
	 * de componentes.<br>
	 * - Creacion de subsistemas y agregacion de los mismos al gestor de subsistemas.
	 */
	public abstract void inicializar();
	/**
	 * Crea una nueva entidad en el sistema.<br>
	 * La entidad creada inicialmente no tiene ningun componente.
	 * @param tipo El tipo de entidad: "jugador", "alien", "nave"...
	 * @return Referencia a la Entidad creada
	 */
	public Entidad crearEntidad(String tipo) {
		Entidad entidad = new Entidad(tipo);
		gestorEntidades.agregarEntidad(entidad);
		return entidad;
	}
	/**
	 * Elimina del sistema una entidad y todos sus componentes.<br>
	 * Este metodo es equivalente a llamar por separado a los metodos:<br>
	 * {@code eliminarComponentes(Entidad)} de {@code GestorComponentes} y
	 * {@code eliminarEntidad(Entidad)} de {@code GestorEntidades}
	 * @param entidad Entidad a eliminar
	 */
	public void eliminarEntidad(Entidad entidad) {
		gestorComponentes.eliminarComponentes(entidad);
		gestorEntidades.eliminarEntidad(entidad);
	}
	/**
	 * Devuelve una entidad a partir de su ID. Si no se encuentra devuelve null.<br>
	 * Este metodo llama al metodo {@code getEntidad(int id)} de {@code GestorEntidades}
	 * @param id ID de la entidad a buscar
	 * @return Entidad
	 */
	public Entidad getEntidad(int id) {
		return gestorEntidades.getEntidad(id);
	}
	/**
	 * Agrega un componente al sistema. El componente debe referenciar a una Entidad.<br>
	 * Si la entidad referenciada ya tenia un componente del mismo tipo, lo sustituye por el nuevo.
	 * @param componente Componente a agregar
	 */
	public void agregarComponente(Componente componente) {
		/*Entidad entidad = componente.getEntidad();
		if (entidad == null) {
			return;
		}
		int ret = entidad.agregarComponente(componente);
		if (ret != -1) {
			gestorComponentes.agregarComponente(componente);
		}
		if (ret >= 0) {
			gestorComponentes.eliminarComponente(ret);
		}*/
		gestorComponentes.agregarComponente(componente);
	}
	/**
	 * Elimina del sistema el componente especificado.
	 * @param componente Componente a eliminar
	 */
	public void eliminarComponente(Componente componente) {
		gestorComponentes.eliminarComponente(componente);
		//componente.getEntidad().eliminarComponente(componente);
	}
	/**
	 * Elimina del sistema todos los componentes asociados a una entidad.
	 * @param entidad Entidad cuyos componentes se quieren eliminar
	 */
	public void eliminarComponentes(Entidad entidad) {
		gestorComponentes.eliminarComponentes(entidad);
		//entidad.eliminarComponentes();
	}
	/**
	 * Elimina todas las entidades, componentes y subsistemas.
	 */
	public void eliminarTodo() {
		gestorEntidades.eliminarTodo();
		gestorComponentes.eliminarTodo();
		gestorSubsistemas.eliminarTodo();
	}
	/**
	 * Devuelve el gestor de entidades
	 * @return GestorEntidades
	 */
	public GestorEntidades getGestorEntidades() {
		return gestorEntidades;
	}
	/**
	 * Devuelve el gestor de componentes
	 * @return GestorComponentes
	 */
	public GestorComponentes getGestorComponentes() {
		return gestorComponentes;
	}
	/**
	 * Devuelve el gestor de subsistemas
	 * @return GestorSubsistemas
	 */
	public GestorSubsistemas getGestorSubsistemas() {
		return gestorSubsistemas;
	}

}
